#include "levelscene.h"

LevelScene::LevelScene(QPixmap mapPixmap, QImage mapMask, QWidget *parent)
    : GameScene((QWidget*)parent)
{
    mainView->setViewport(GLWidget); //use openGL rendering

    // Create the background
    map = new GameBackground(mapPixmap,mainScene);
    QObject::connect(map,SIGNAL(backgroundClicked(QPointF)),this,SLOT(mapClicked(QPointF)));

    // Setup the scene viewport for the size of map we are using
    mainScene->setSceneRect(0,0,map->pixmap().rect().width(),map->pixmap().rect().height() + 150);
    mainView->centerView();

    // Setup the tools panel
    panelScene = new QGraphicsScene(0,0,this->width(),150,this);
    panelView = new QGraphicsView(panelScene,mainView);

    panelView->resize(this->width(),150);
    panelView->move(0,this->height()-150);
    panelView->setStyleSheet("background: transparent");
    panelView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    panelView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    panelView->setFrameStyle(QFrame::NoFrame);

    panelBackground = new GameBackground(QPixmap(RESOURCE_DIR + "/Kit_ToolBarBackground.png"),panelScene);

    currentTool = 0;

    //Make the minimap
    miniMap = new MiniMap(mapPixmap,&buildings,panelScene,mainView);
    miniMap->setPos(width()-miniMap->mapRectToScene(miniMap->pixmap().rect()).width() - 10,10);
    miniMap->screenRect->screenPanned(mainView->getCenterPoint());
    QObject::connect(miniMap->screenRect,SIGNAL(screenMove(QPointF)),mainView,SLOT(screenMoved(QPointF)));
    QObject::connect(mainView,SIGNAL(screenPanned(QPointF)),miniMap->screenRect,SLOT(screenPanned(QPointF)));

    //Setup options panel
    optionsPanel = new OptionsPanel(this);
    optionsPanel->move((width()/2)-(optionsPanel->width()/2),((height()-150)/2)-(optionsPanel->height()/2));
    QObject::connect(optionsPanel,SIGNAL(endScene(GameScene::GameScenes)),this,SLOT(endScene(GameScene::GameScenes)));
    QObject::connect(optionsPanel,SIGNAL(resumeScene()),this,SLOT(resumeScene()));

    statsTimer = new QTimer();
    statsTimer->start(500);
    QObject::connect(statsTimer,SIGNAL(timeout()),this,SLOT(updateStats()));

    stats = new StatsDisplay(panelScene);
    stats->setPos(miniMap->pos().x()-stats->boundingRect().width()-50,10);

    //----------------------------------------------------------------------
    // Initilize the path finding stuff
    //----------------------------------------------------------------------

    pathFinder = new PathFinder(mapMask,this);
    QObject::connect(pathFinder,SIGNAL(pathSolved(std::vector<void*>,QObject*)),this,SLOT(pathSolved(std::vector<void*>,QObject*)));

    //******** Uncomment the following line to draw the passible points on the map
    //visualizer = new PathMapVisualizer(pathFinder->getPathMap(),mainScene);
}

void LevelScene::start()
{
    mainView->setPanEnabled(true);
    pathFinder->start();
    people.last()->treatPerson();
    grabKeyboard();
    stats->setStartPopulation(people.length());

    //Uncomment this if you want to save the buildings as an image
    //saveBuildingImage();

    emit startPeople();
}

void LevelScene::endScene(GameScene::GameScenes nextScene)
{
    releaseKeyboard();
    optionsPanel->setEnabled(false);
    emit stopPeople();
    saveBuildingImage();
    GameScene::endScene(nextScene);
    deleteLater();
}

void LevelScene::pauseScene()
{
    panelView->setInteractive(false);
    GameScene::pauseScene();
    emit stopPeople();
}

void LevelScene::resumeScene()
{
    panelView->setInteractive(true);
    GameScene::resumeScene();
    emit startPeople();
}

ToolButton * LevelScene::addTool(QString caption, QPixmap toolIcon)
{
    tools.append(new ToolButton(caption,toolIcon,panelScene));
    tools.last()->setPos(10 + ((tools.length()-1)*55),10);

    QObject::connect(tools.last(),SIGNAL(clicked(ToolButton*)),this,SLOT(toolClicked(ToolButton*)));

    return tools.last();
}

Building * LevelScene::addBuilding(QPoint enterence, QPointF position, QPixmap buildingPixmap)
{
    buildings.append(new Building(enterence,buildingPixmap,mainScene));
    buildings.last()->setPos(position);

    QObject::connect(buildings.last(),SIGNAL(clicked(Building*)),this,SLOT(buildingClicked(Building*)));

    return buildings.last();
}

Person * LevelScene::addPerson(QPixmap personPixmap, Building *startingBuilding)
{
    people.append(new Person(pathFinder->getPathMap(), personPixmap, this, mainScene));
    QObject::connect(people.last(),SIGNAL(solvePath(QPoint,QPoint,QObject*)),pathFinder,SLOT(solvePath(QPoint,QPoint,QObject*)));
    QObject::connect(this,SIGNAL(startPeople()),people.last(),SLOT(startPerson()));
    QObject::connect(this,SIGNAL(stopPeople()),people.last(),SLOT(stopPerson()));
    enterBuilding(people.last(),startingBuilding);
    people.last()->setPos(startingBuilding->getEnterencePoint()*10);
    return people.last();
}

void LevelScene::pathSolved(std::vector<void *>path, QObject *receiver)
{
    people.at(people.indexOf((Person*)receiver))->setPath(path);
}

void LevelScene::enterBuilding(Person *person, Building *building)
{
    // Add them to the new building
    building->addPerson(person);
    person->setCurrentBuilding(building);
}

void LevelScene::leaveBuilding(Person *person, Building *building)
{
    // If the person is currently in a building, remove them
    if (building != 0)
        building->removePerson(person);
}

void LevelScene::toolClicked(ToolButton *sender)
{
    if (sender->getSate())
    {
        if (currentTool)
            currentTool->releaseButton();
        currentTool = sender;
    }
    else
        currentTool = 0;
}

void LevelScene::buildingClicked(Building *sender)
{
    if (currentTool != 0)
    {
        if (currentTool == sterilizationTool)
            Tools::Sterilization(sender);

        if (currentTool == vacceneTool)
            Tools::Vaccene(sender);

        if (currentTool == antiviralTool)
            Tools::Antivirals(sender);

        if (currentTool == gammaglobulinTool)
            Tools::Gammaglobulins(sender);

        if (currentTool == geneTherapyTool)
            Tools::GeneTherapy(sender);

        currentTool->releaseButton();
        currentTool = 0;
    }
}

void LevelScene::mapClicked(QPointF point)
{
    // convert point into a grid position
    point /= 10;

    if ((currentTool == quarantineTool) &&
        (pathFinder->getPathMap()->IsPointPassable((int)point.x(),(int)point.y())))
    {
        pathFinder->setPointPassable((int)point.x(),(int)point.y(),false);
        roadBlocks.append(new QGraphicsPixmapItem(RESOURCE_DIR + "/RoadBlock.png",0,mainScene));
        roadBlocks.last()->setPos(((int)point.x())*10,((int)point.y())*10);
        roadBlocks.last()->setData(ITEM_TYPE,GameItems::RoadBlock);

        currentTool->releaseButton();
        currentTool = 0;
    }

}

void LevelScene::checkCollisions()
{
    for (int currentPerson = 0; currentPerson < people.length(); currentPerson++)
    {
        for (int testPerson = (currentPerson+1); testPerson < people.length(); testPerson++)
        {
            if ((people.at(currentPerson)->isVisible()) && (people.at(testPerson)->isVisible()))  // if both people are visible
            {
                if (people.at(currentPerson)->collidesWithItem(people.at(testPerson),Qt::IntersectsItemBoundingRect)) // if there is a collision between the two people
                    people.at(currentPerson)->collidesWithPerson(people.at(testPerson));
            }
        }
    }

}

void LevelScene::timerEvent(QTimerEvent *event)
{
    GameScene::timerEvent(event);
    checkCollisions();
}

void LevelScene::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Escape)
    {
        pauseScene();
        optionsPanel->setEnabled(true);
    }
}


void LevelScene::updateStats()
{
    int newInfected = 0;

    for (int index = 0; index < people.length(); index++)
    {
        if (people.at(index)->virus != 0)
            newInfected++;
    }

    stats->setStats(people.length(),newInfected);
}

void LevelScene::saveBuildingImage()
{
    //QGraphicsRectItem * mask = mainScene->addRect(mainScene->sceneRect(),QPen(Qt::NoPen),QBrush(QColor(255,0,255),Qt::SolidPattern));
    QImage * saveImage = new QImage((int)mainScene->sceneRect().width(),(int)mainScene->sceneRect().height(),QImage::Format_ARGB32);
    QPainter * painter = new QPainter(saveImage);
    mainScene->render(painter);
    saveImage->save(RESOURCE_DIR + "/scene.png","PNG",-1);
    //delete mask;
}
